package com.jeejio.common.rcv.decoration

import android.graphics.Canvas
import android.graphics.Paint
import android.graphics.Rect
import android.view.View
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView

/**
 * Author: JFangZ
 * Email: janezhang1901@163.com
 * Date: 2021/4/19 10:09
 * Description:The divider style decoration for linear layout manager.
 */
class LinearDividerDecoration(builder: Builder) : RecyclerView.ItemDecoration() {
    private var width = 1
    private var marginLeft = 0
    private var marginTop = 0
    private var marginRight = 0
    private var marginBottom = 0
    private var firstItemTop = false
    private var lastItemBottom = false
    private var offset = true

    private val outRect = Rect()
    private val paint = Paint()

    init {
        width = builder.width
        marginLeft = builder.marginLeft
        marginTop = builder.marginTop
        marginRight = builder.marginRight
        marginBottom = builder.marginBottom
        firstItemTop = builder.firstItemTop
        lastItemBottom = builder.lastItemBottom
        offset = builder.offset
        paint.isAntiAlias = true
        paint.color = builder.color
    }

    override fun getItemOffsets(outRect: Rect, view: View, parent: RecyclerView, state: RecyclerView.State) {
        if (!offset) {
            return
        }
        val layoutManager = parent.layoutManager as? LinearLayoutManager ?: return
        val adapter = parent.adapter ?: return
        // 获取当前itemView的位置
        val position = parent.getChildAdapterPosition(view)
        val itemCount = adapter.itemCount
        if (layoutManager.orientation == RecyclerView.VERTICAL) {
            // 纵向分隔线
            // (position == 0 && mFirstItemTop) 表示第一个 item 顶部需要显示分隔线
            if (position == 0 && firstItemTop) {
                outRect.top = width
            }
            // (position == parent.getAdapter().getItemCount() - 1 && mLastItemBottom) 表示最后一个 item 底部需要显示分隔线
            if (position < itemCount - 1 || position == itemCount - 1 && lastItemBottom) {
                outRect.bottom = width
            }
        } else {
            // 横向分隔线
            // (position == 0 && mFirstItemTop) 表示第一个 item 左边需要显示分隔线
            if (position == 0 && firstItemTop) {
                outRect.left = width
            }
            // (position == parent.getAdapter().getItemCount() - 1 && mLastItemBottom) 表示最后一个 item 右边需要显示分隔线
            if (position < itemCount - 1 || position == itemCount - 1 && lastItemBottom) {
                outRect.right = width
            }
        }
    }

    override fun onDrawOver(c: Canvas, parent: RecyclerView, state: RecyclerView.State) {
        val layoutManager = (parent.layoutManager ?: return) as? LinearLayoutManager ?: return
        if (layoutManager.orientation == RecyclerView.VERTICAL) {
            drawVertical(c, parent, state)
        } else {
            drawHorizontal(c, parent, state)
        }
    }

    /**
     * Author: JFangZ
     * Email: janezhang1901@163.com
     * Date:2020/7/6 22:23
     * Description:绘制纵向的分隔线
     */
    private fun drawVertical(canvas: Canvas, parent: RecyclerView, state: RecyclerView.State) {
        // 获取 RecyclerView 的 Item 数量
        val childCount = parent.childCount
        val adapter = parent.adapter ?: return
        val itemCount = adapter.itemCount
        for (i in 0 until childCount) {
            val childView = parent.getChildAt(i)
            val position = parent.getChildAdapterPosition(childView)
            getItemOffsets(outRect, childView, parent, state)
            if (position == 0 && firstItemTop) {
                canvas.drawRect((childView.left + marginLeft
                        ).toFloat(), (childView.top - outRect.top
                        ).toFloat(), (childView.right - marginRight
                        ).toFloat(), (childView.top - outRect.top + width
                        ).toFloat(), paint)
            }
            if (position < itemCount - 1 || position == itemCount - 1 && lastItemBottom) {
                canvas.drawRect((childView.left + marginLeft
                        ).toFloat(), (childView.bottom + outRect.bottom - width
                        ).toFloat(), (childView.right - marginRight
                        ).toFloat(), (childView.bottom + outRect.bottom
                        ).toFloat(), paint)
            }
        }
    }

    /**
     * Author: JFangZ
     * Email: janezhang1901@163.com
     * Date:2020/7/6 22:23
     * Description:绘制横向的分隔线
     */
    private fun drawHorizontal(canvas: Canvas, parent: RecyclerView, state: RecyclerView.State) {
        // 获取 RecyclerView 的 Item 数量
        val childCount = parent.childCount
        val adapter = parent.adapter ?: return
        val itemCount = adapter.itemCount
        for (i in 0 until childCount) {
            val childView = parent.getChildAt(i)
            val position = parent.getChildAdapterPosition(childView)
            getItemOffsets(outRect, childView, parent, state)
            if (position == 0 && firstItemTop) {
                canvas.drawRect((childView.left - outRect.left
                        ).toFloat(), (childView.top - marginTop
                        ).toFloat(), (childView.left - outRect.left
                        ).toFloat(), (childView.bottom - marginBottom
                        ).toFloat(), paint)
            }
            if (position < itemCount - 1 || position == itemCount - 1 && lastItemBottom) {
                canvas.drawRect((childView.right + outRect.right - width
                        ).toFloat(), (childView.top - marginTop
                        ).toFloat(), (childView.right + outRect.right
                        ).toFloat(), (childView.bottom - marginBottom
                        ).toFloat(), paint)
            }
        }
    }

    class Builder {
        internal var width = 1
        internal var marginLeft = 0
        internal var marginTop = 0
        internal var marginRight = 0
        internal var marginBottom = 0
        internal var firstItemTop = false
        internal var lastItemBottom = false
        internal var offset = true
        internal var color = 0x00000000

        /**
         * Author: JFangZ
         * Email: janezhang1901@163.com
         * Date:2021/4/19 15:31
         * Description:Set the height of divider when layout's orientation is vertical,or the width
         * of divider when layout's orientation is horizontal.
         */
        fun setWidth(width: Int): Builder {
            this.width = width
            return this
        }

        /**
         * Author: JFangZ
         * Email: janezhang1901@163.com
         * Date:2021/4/19 15:31
         * Description:Set the color of divider.
         */
        fun setColor(color: Int): Builder {
            this.color = color
            return this
        }

        /**
         * Author: JFangZ
         * Email: janezhang1901@163.com
         * Date:2021/4/19 15:31
         * Description:Set the margin left,If effective only layout's orientation is horizontal.
         */
        fun setMarginLeft(marginLeft: Int): Builder {
            this.marginLeft = marginLeft
            return this
        }

        /**
         * Author: JFangZ
         * Email: janezhang1901@163.com
         * Date:2021/4/19 15:31
         * Description:Set the margin top,If effective only layout's orientation is horizontal.
         */
        fun setMarginTop(marginTop: Int): Builder {
            this.marginTop = marginTop
            return this
        }

        /**
         * Author: JFangZ
         * Email: janezhang1901@163.com
         * Date:2021/4/19 15:31
         * Description:Set the margin right,If effective only layout's orientation is horizontal.
         */
        fun setMarginRight(marginRight: Int): Builder {
            this.marginRight = marginRight
            return this
        }

        /**
         * Author: JFangZ
         * Email: janezhang1901@163.com
         * Date:2021/4/19 15:31
         * Description:Set the margin bottom,If effective only layout's orientation is horizontal.
         */
        fun setMarginBottom(marginBottom: Int): Builder {
            this.marginBottom = marginBottom
            return this
        }

        /**
         * Author: JFangZ
         * Email: janezhang1901@163.com
         * Date:2021/4/19 15:31
         * Description:Set show divider at the top of first item or not.
         */
        fun setFirstItemTop(firstItemTop: Boolean): Builder {
            this.firstItemTop = firstItemTop
            return this
        }

        /**
         * Author: JFangZ
         * Email: janezhang1901@163.com
         * Date:2021/4/19 15:31
         * Description:Set show divider at the bottom of last item or not.
         */
        fun setLastItemBottom(lastItemBottom: Boolean): Builder {
            this.lastItemBottom = lastItemBottom
            return this
        }

        /**
         * Author: JFangZ
         * Email: janezhang1901@163.com
         * Date:2021/4/19 15:30
         * Description:Set the divider will add the padding of item or not.
         */
        fun setOffset(offset: Boolean): Builder {
            this.offset = offset
            return this
        }

        fun build(): LinearDividerDecoration {
            return LinearDividerDecoration(this)
        }
    }
}